#include "tcpclient.h"
#include "printf_rtos.h"
#include "projdefs.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lwip/sockets.h"
/**
 * @brief TCP回显客户端任务函数，用于创建TCP客户端并连接到服务器，发送数据并接收回显。
 *
 * 该任务运行在一个FreeRTOS任务中，持续尝试连接到指定的TCP服务器，
 * 成功连接后周期性地发送测试消息，并打印服务器返回的回显内容。
 *
 * @param pvParameters 任务参数，未使用，可为NULL。
 */
void tcp_echo_client_task(void * pvParameters) {
	printf_rtos("TCP ECHO TEST CLIENT TASK START\n");
	int client_socket = -1;
	// 客户端套接字描述符
	bool isConnected = false;
	// 连接状态标志
	struct sockaddr_in server_addr = {
		0
	}
	;
	// 服务器地址结构体
	uint16_t sendCNT=0;
	// 主循环：尝试连接服务器并进行数据收发
	for (;;) {
		// 如果未连接，则尝试建立连接
		if (isConnected == false) {
			// 创建TCP套接字，第三个参数为协议号，0表示使用默认协议（TCP）
			client_socket = socket(AF_INET, SOCK_STREAM, 0);
			if (client_socket < 0) {
				printf_rtos("Failed to creat socket,errno'%d,retry\n", errno);
				vTaskDelay(500);
				continue;
			}
			printf_rtos("socket creat successfully\n");
			// 初始化服务器地址结构体
			memset(&server_addr, 0, sizeof(server_addr));
			server_addr.sin_family = AF_INET;
			server_addr.sin_port = htons(SERVER_PORT);
			// 设置服务器端口
			server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
			// 设置服务器IP地址
			printf_rtos("connecting to server %s:%d...\n", SERVER_IP, SERVER_PORT);
			// 尝试连接到服务器
			if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
				printf_rtos("connect failed,errno:%d,retry\n", errno);
				closesocket(client_socket);
				// 连接失败则关闭套接字并重试
				vTaskDelay(500);
				continue;
			}
			printf_rtos("connect server successfully\n");
		}
		// 标记连接已建立
		isConnected = true;
		// 准备发送和接收缓冲区
		// 准备发送和接收缓冲区
		char sendBuf[64] = {0}; // 同样，先定义一个足够大的缓冲区
		char recv_buf[128] = {0};
		int recv_len;

		// 使用 snprintf，它更安全！
		// 第一个参数是目标buffer，第二个是buffer的最大容量，后面和sprintf一样
		snprintf(sendBuf, sizeof(sendBuf), "Message count:%d\n", ++sendCNT);

		// 发送数据到服务器
		if (send(client_socket, sendBuf, strlen(sendBuf), 0) < 0)
		{
			printf_rtos("send failed,errno:%d\n", errno);
			vTaskDelay(500);
			continue;
		}
		printf_rtos("send:%s\n", sendBuf);
		// 接收服务器回显数据
		recv_len = recv(client_socket, recv_buf, sizeof(recv_buf) - 1, 0);
		if (recv_len < 0) {
			printf_rtos("recv failed,errno:%d\n", errno);
			vTaskDelay(500);
			continue;
			// 接收失败则继续接收
		} else if (recv_len == 0) {
			printf_rtos("server closed\n");
			vTaskDelete(NULL);
			// 删除当前任务
		}
		// 添加字符串结束符并打印接收到的数据
		recv_buf[recv_len] = '\0';
		printf_rtos("received:%s\n", recv_buf);
		// 延时一段时间后继续下一次发送
		vTaskDelay(pdMS_TO_TICKS(50));
	}
	// 关闭套接字并结束任务
	printf_rtos("closing socket\n");
	closesocket(client_socket);
	printf_rtos("tcp echo client task finished\n");
	vTaskDelete(NULL);
	// 删除当前任务
}